Import¶

In [1]:
import pandas as pd
import numpy as np
import plotly.express as px
import re

from tqdm.notebook import tqdm

pd.set_option('display.width', 1000)
In [2]:
date = "2024_08_24"
In [3]:
data = pd.read_csv(f"data/data_{date}.csv", sep = ";")

Autor + Geschlecht¶

In [4]:
data['Autor'] = [x.strip() if pd.notna(x) else x for x in data['Autor']]
In [5]:
data['Geschlecht'] = [x.strip() if pd.notna(x) else x for x in data['Geschlecht']]

Zeit¶

In [6]:
data['Jahreszahl_Statistik'] = data['Jahreszahl_Statistik'].astype(float)
In [7]:
data['Dekade'] = [(x//10) * 10 for x in data['Jahreszahl_Statistik']]
data['Jahrhundert'] = [(x//100) * 100 for x in data['Jahreszahl_Statistik']]
In [8]:
data[['Autor', 'Titel', 'Jahreszahl_Statistik', 'Dekade', 'Jahrhundert']].head()
Out[8]:
Autor Titel Jahreszahl_Statistik Dekade Jahrhundert
0 (Pfaffe Konrad) Rolandslied 1172.0 1170.0 1100.0
1 $Arthur Quiller-Couch, Arthur The Oxford Book of English Verse NaN NaN NaN
2 $Bahr, Ehrhard (Hg.) Was ist Aufklärung? Thesen und Definitionen 1974.0 1970.0 1900.0
3 $Beers, Anna (Hg.) Frauen / Lyrik. Gedichte in deutscher Sprache 2020.0 2020.0 2000.0
4 $Behrens, Katja (Hg.) Frauenbriefe der Romantik 1982.0 1980.0 1900.0

Module¶

In [9]:
data = data.rename(columns = {
    'Modul_Zeit_vor_17.Jh.' : 'Modul_Zeit',
    'Modul_Sprache_(international)' : 'Modul_Sprache',
    'Modul: KJL' : 'Modul_KJL',
})

Leselisten¶

In [10]:
leselisten_dict = {
    'Aachen' : 'Aachen1',
    'Berlin' : 'FU Berlin',
    'Innsbruck' : 'Innsbruck1',
    'Innsbruck 2023' : 'Innsbruck2',
    'Köln Fundamentum' : 'Köln',
    'LA Aachen' : 'Aachen2',
    'Stuttgart' : 'Stuttgart1',
    'Stuttgart 2022' : 'Stuttgart2',
    'Würzburg' : 'Würzburg1',
    'Würzburg_2019' : 'Würzburg2',
}

data = data.rename(columns=leselisten_dict)
In [11]:
leselisten_dict2 = {
    'Aachen1' : 'Aachen 2017/18',
    'Augsburg' : 'Augsburg 2020',
    'FU Berlin' : 'FU Berlin o.J.',
    'Bochum' : 'Bochum o.J.',
    'Braunschweig' : 'Braunschweig o.J.',
    'Dortmund' : 'Dortmund o.J.',
    'Eichstätt-Ingolstadt' : 'Eichstätt-Ingolstadt 2007',
    'Frankfurt a.M.' : 'Frankfurt a.M. o.J.',
    'Gießen' : 'Gießen o.J.',
    'Göttingen' : 'Göttingen o.J.',
    'Graz' : 'Graz 2021',
    'Heidelberg' : 'Heidelberg 2017',
    'Hildesheim' : 'Hildesheim o.J.',
    'Innsbruck1' : 'Innsbruck o.J.',
    'Innsbruck2' : 'Innsbruck 2023',
    'Jena' : 'Jena 2018',
    'Karlsruhe' : 'Karlsruhe o.J.',
    'Koblenz' : 'Koblenz o.J.',
    'Köln' : 'Köln o.J.',
    'Aachen2' : 'LA Aachen 2018',
    'Lausanne' : 'Lausanne o.J.',
    'Leipzig' : 'Leipzig o.J.',
    'Lüneburg' : 'Lüneburg o.J.',
    'Luxemburg' : 'Luxemburg o.J.',
    'Magdeburg' : 'Magdeburg 2020',
    'Mannheim' : 'Mannheim o.J.',
    'München' : 'München o.J.',
    'Oldenburg' : 'Oldenburg 2020',
    'Osnabrück' : 'Osnabrück o.J.',
    'Passau' : 'Passau o.J.',
    'Potsdam' : 'Potsdam 2022',
    'Saarland' : 'Saarland 2007',
    'Salzburg' : 'Salzburg o.J.',
    'Stuttgart1' : 'Stuttgart o.J.',
    'Stuttgart2' : 'Stuttgart 2022',
    'Trier' : 'Trier o.J.',
    'Tübingen' : 'Tübingen o.J.',
    'Wien' : 'Wien o.J.',
    'Wuppertal' : 'Wuppertal 2015',
    'Würzburg1' : 'Würzburg 2003/04',
    'Würzburg2' : 'Würzburg 2019',
    'Zürich' : 'Zürich 2013',
}

data = data.rename(columns=leselisten_dict2)
In [12]:
leselisten = [x for x in data.columns if x not in [
                  'Autor', 'GND', 'Titel', 'Geschlecht',
                  'Jahreszahl', 'Jahreszahl_Statistik', 'Dekade', 'Jahrhundert',
                  'Gattung',
                  'Modul_Zeit', 'Modul_Sprache', 'Modul_KJL'
              ]]
leselisten = sorted(leselisten)
In [13]:
def convert_to_float(frac_str):
    # Replace comma with a dot and fraction slash with standard slash
    if type(frac_str) == str:
        frac_str = frac_str.replace(",", ".").replace("⁄", "/")
    
    # Try to convert directly to float
    try:
        return float(frac_str)
        
    # Handle mixed number (e.g., "1 1/2") or proper fraction (e.g., "1/2")
    except ValueError:
        if ' ' in frac_str:
            whole, frac_part = frac_str.split(' ')
            return float(whole) + eval(frac_part)
        else:
            return eval(frac_str)
In [14]:
data[leselisten] = data[leselisten].map(convert_to_float)
data[leselisten] = data[leselisten].astype(float).fillna(0)

Leselisten-Meta¶

In [15]:
leselisten_meta = pd.read_excel("data/Leselisten_meta.xlsx")[['Leseliste', 'Datum_quant']]
leselisten_meta['Leseliste'] = leselisten_meta['Leseliste'].replace(leselisten_dict).replace(leselisten_dict2)
leselisten_meta = leselisten_meta.rename(columns={'Datum_quant' : 'Datum'})
In [16]:
leselisten_meta.head()
Out[16]:
Leseliste Datum
0 Aachen 2017/18 2017.0
1 Augsburg 2020 2020.0
2 NaN NaN
3 FU Berlin o.J. NaN
4 Bochum o.J. NaN

Check¶

In [17]:
data[[
    'Autor', 'Titel',
    'Jahreszahl_Statistik', 'Dekade',
    'Gattung',
    'Aachen 2017/18', 'FU Berlin o.J.', 'Stuttgart o.J.',
]].sample(n=5)
Out[17]:
Autor Titel Jahreszahl_Statistik Dekade Gattung Aachen 2017/18 FU Berlin o.J. Stuttgart o.J.
939 Goetz, Rainald Loslabern. Bericht 2008 2009.0 2000.0 Prosa 0.0 0.0 0.0
641 Eich, Günter Abgelegene Gehöfte 1948.0 1940.0 Lyrik 0.0 0.0 0.0
1778 Logau, Friedrich von Sinngedichte 1630.0 1630.0 Lyrik 0.0 0.0 0.0
2224 Sachs, Hans Der farent Schüler ins Paradeis 1561.0 1560.0 Drama 0.0 0.0 0.0
2538 Toller, Ernst Hinkemann 1921.0 1920.0 Drama 0.0 0.0 0.0
In [18]:
print(f"Vorhandene Leselisten : {len(leselisten)}")
print(f"Vorhandene Einträge   : {data.shape[0]}")
print(f"Fehlende Autornamen   : {data.query('Autor.isna()').shape[0]}")
print(f"Fehlende Titel        : {data.query('Titel.isna()').shape[0]}")
print(f"Fehlende Jahreszahlen : {data.query('Jahreszahl_Statistik.isna()').shape[0]}")
print(f"Fehlende Gattungen    : {data.query('Gattung.isna()').shape[0]}")
Vorhandene Leselisten : 42
Vorhandene Einträge   : 2792
Fehlende Autornamen   : 26
Fehlende Titel        : 9
Fehlende Jahreszahlen : 78
Fehlende Gattungen    : 49

Export¶

In [19]:
data.to_csv(f"data/data_{date}_clean.tsv", sep = "\t")

Filter¶

In [20]:
data = (data
        .query("Modul_Zeit != 'Antike'")
        .query("Modul_Zeit != 'MA'")
        .query("Jahreszahl_Statistik >= 1600")
        .query("Modul_Sprache != 'International'")
).reset_index(drop=True).copy()
In [21]:
# Texte ausschließen, die mit $ beginnen (Anthologien)
data = data[~data['Autor'].str.startswith('$', na = False)]

Metriken¶

In [22]:
# AnzahlGenannt: in wie vielen Leselisten wird der Text genannt? (0.33, 0.5 usw. nicht berücksichtigt)
data_leselisten_binary = data[leselisten].copy()
data_leselisten_binary[data_leselisten_binary > 0] = 1
data['AnzahlGenannt'] = data_leselisten_binary.sum(axis=1)
data['AnzahlGenannt_Rang'] = data['AnzahlGenannt'].rank(ascending=False)

# AnzahlGenannt_normalisiert: wie viel % der genannten Titel macht der Text im Durchschnitt der Leselisten aus?
data_leselisten_binary_normalized = data_leselisten_binary/data_leselisten_binary.sum()
data['AnzahlGenannt_normalisiert'] = data_leselisten_binary_normalized.mean(axis=1)
data['AnzahlGenannt_normalisiert_Rang'] = data['AnzahlGenannt_normalisiert'].rank(ascending=False)

# AnzahlZuLesen: wie oft muss der Text über alle Leselisten hinweg gelesen werden? (0.33, 0.5 usw. berücksichtigt)
data_leselisten = data[leselisten]
data['AnzahlZuLesen'] = data_leselisten.sum(axis = 1)
data['AnzahlZuLesen_Rang'] = data['AnzahlZuLesen'].rank(ascending=False)

# AnzahlZuLesen_normalisiert: wie viel % der vorgeschriebenen Lektürevorgänge macht der Text im Durchschnitt der Leselisten aus?
data_leselisten_normalized = data[leselisten]/data[leselisten].sum()
data['AnzahlZuLesen_normalisiert'] = data_leselisten_normalized.mean(axis = 1)
data['AnzahlZuLesen_normalisiert_Rang'] = data['AnzahlZuLesen_normalisiert'].rank(ascending=False)

Test (Titel)¶

In [23]:
test_titel = ['Effi Briest', 'Maria Stuart', 'Die Leute von Seldwyla', 'Die letzte Welt']

data.query("Titel.isin(@test_titel)")[[
    'Autor', 'Titel', 
    'AnzahlGenannt', 'AnzahlGenannt_normalisiert',
    'AnzahlZuLesen', 'AnzahlZuLesen_normalisiert'
]]
Out[23]:
Autor Titel AnzahlGenannt AnzahlGenannt_normalisiert AnzahlZuLesen AnzahlZuLesen_normalisiert
664 Fontane, Theodor Effi Briest 38.0 0.006438 25.030159 0.006389
1407 Keller, Gottfried Die Leute von Seldwyla 20.0 0.002828 14.061265 0.002766
1941 Ransmayr, Christoph Die letzte Welt 20.0 0.001964 12.027927 0.001670
2072 Schiller, Friedrich Maria Stuart 31.0 0.004734 22.328336 0.004741
In [24]:
test_titel = 'Effi Briest'

test_df = pd.DataFrame()
for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste_titel = data_leseliste.query("Titel.str.contains(@test_titel, na = False)").copy()

    test_df.at[leseliste, 'AnzahlGenannt_gesamt'] = data_leseliste.shape[0]
    if data_leseliste_titel.shape[0] > 0:
        test_df.at[leseliste, 'AnzahlGenannt_DieserTitel'] = data_leseliste_titel.shape[0]
        test_df.at[leseliste, 'AnzahlGenannt_DieserTitel_normalisiert'] = data_leseliste_titel.shape[0]/data_leseliste.shape[0]
        
    test_df.at[leseliste, 'AnzahlZuLesen_gesamt'] = data_leseliste[leseliste].sum()
    if data_leseliste_titel.shape[0] > 0:
        test_df.at[leseliste, 'AnzahlZuLesen_DieserTitel'] = data_leseliste_titel[leseliste].sum()
        test_df.at[leseliste, 'AnzahlZuLesen_DieserTitel_normalisiert'] = data_leseliste_titel[leseliste].sum()/data_leseliste[leseliste].sum()

test_df = test_df.fillna(0)
test_df[['AnzahlGenannt_gesamt', 'AnzahlGenannt_DieserTitel']] = test_df[['AnzahlGenannt_gesamt', 'AnzahlGenannt_DieserTitel']].astype(int)
In [25]:
test_df.head()
Out[25]:
AnzahlGenannt_gesamt AnzahlGenannt_DieserTitel AnzahlGenannt_DieserTitel_normalisiert AnzahlZuLesen_gesamt AnzahlZuLesen_DieserTitel AnzahlZuLesen_DieserTitel_normalisiert
Aachen 2017/18 347 1 0.002882 44.880692 0.076923 0.001714
Augsburg 2020 107 0 0.000000 107.000000 0.000000 0.000000
Bochum o.J. 98 1 0.010204 95.000000 1.000000 0.010526
Braunschweig o.J. 221 1 0.004525 56.828929 0.238095 0.004190
Dortmund o.J. 231 1 0.004329 172.000000 0.333333 0.001938
In [26]:
print(f"AnzahlGenannt               : {test_df['AnzahlGenannt_DieserTitel'].sum()}")
print(f"AnzahlGenannt_normalisiert  : {test_df['AnzahlGenannt_DieserTitel_normalisiert'].mean()}")
print(f"AnzahlZuLesen               : {test_df['AnzahlZuLesen_DieserTitel'].sum()}")
print(f"AnzahlZuLesen_normalisiert  : {test_df['AnzahlZuLesen_DieserTitel_normalisiert'].mean()}")
AnzahlGenannt               : 38
AnzahlGenannt_normalisiert  : 0.006437970694534374
AnzahlZuLesen               : 25.03015880617565
AnzahlZuLesen_normalisiert  : 0.00638897152681453

Test (Autor)¶

In [27]:
test_authors = ['Fontane, Theodor', 'Keller, Gottfried', 'Ransmayr, Christoph', 'Schiller, Friedrich']

data_autoren = data.groupby('Autor')[[
    'AnzahlGenannt', 'AnzahlGenannt_normalisiert',
    'AnzahlZuLesen', 'AnzahlZuLesen_normalisiert'
]].sum()
data_autoren_specific = data_autoren.loc[test_authors]

data_autoren_specific
Out[27]:
AnzahlGenannt AnzahlGenannt_normalisiert AnzahlZuLesen AnzahlZuLesen_normalisiert
Autor
Fontane, Theodor 99.0 0.012514 59.044436 0.012084
Keller, Gottfried 83.0 0.010405 53.915727 0.010495
Ransmayr, Christoph 25.0 0.002252 15.064927 0.001846
Schiller, Friedrich 258.0 0.032072 166.424373 0.033645
In [28]:
test_author = 'Fontane, Theodor'

test_df = pd.DataFrame()
for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste_autor = data_leseliste.query("Autor.str.contains(@test_author, na = False)").copy()

    test_df.at[leseliste, 'AnzahlGenannt_gesamt'] = data_leseliste.shape[0]
    if data_leseliste_titel.shape[0] > 0:
        test_df.at[leseliste, 'AnzahlGenannt_Autor'] = data_leseliste_autor.shape[0]
        test_df.at[leseliste, 'AnzahlGenannt_Autor_normalisiert'] = data_leseliste_autor.shape[0]/data_leseliste.shape[0]
        
    test_df.at[leseliste, 'AnzahlZuLesen_gesamt'] = data_leseliste[leseliste].sum()
    if data_leseliste_titel.shape[0] > 0:
        test_df.at[leseliste, 'AnzahlZuLesen_Autor'] = data_leseliste_autor[leseliste].sum()
        test_df.at[leseliste, 'AnzahlZuLesen_Autor_normalisiert'] = data_leseliste_autor[leseliste].sum()/data_leseliste[leseliste].sum()

test_df = test_df.fillna(0)
test_df[['AnzahlGenannt_gesamt', 'AnzahlGenannt_Autor']] = test_df[['AnzahlGenannt_gesamt', 'AnzahlGenannt_Autor']].astype(int)
In [29]:
test_df.head()
Out[29]:
AnzahlGenannt_gesamt AnzahlGenannt_Autor AnzahlGenannt_Autor_normalisiert AnzahlZuLesen_gesamt AnzahlZuLesen_Autor AnzahlZuLesen_Autor_normalisiert
Aachen 2017/18 347 2 0.005764 44.880692 0.153846 0.003428
Augsburg 2020 107 1 0.009346 107.000000 1.000000 0.009346
Bochum o.J. 98 1 0.010204 95.000000 1.000000 0.010526
Braunschweig o.J. 221 2 0.009050 56.828929 0.476190 0.008379
Dortmund o.J. 231 3 0.012987 172.000000 1.000000 0.005814
In [30]:
print(f"AnzahlGenannt               : {test_df['AnzahlGenannt_Autor'].sum()}")
print(f"AnzahlGenannt_normalisiert  : {test_df['AnzahlGenannt_Autor_normalisiert'].mean()}")
print(f"AnzahlZuLesen               : {test_df['AnzahlZuLesen_Autor'].sum()}")
print(f"AnzahlZuLesen_normalisiert  : {test_df['AnzahlZuLesen_Autor_normalisiert'].mean()}")
AnzahlGenannt               : 99
AnzahlGenannt_normalisiert  : 0.01251437452976308
AnzahlZuLesen               : 59.04443600771096
AnzahlZuLesen_normalisiert  : 0.0120839909209064

Check2¶

In [31]:
data[[
    'Autor', 'Titel',
    'Jahreszahl_Statistik', 'Dekade',
    'Gattung',
    'Aachen 2017/18', 'FU Berlin o.J.', 'Stuttgart o.J.',
    'AnzahlZuLesen', 'AnzahlGenannt'
]].sample(n=5)
Out[31]:
Autor Titel Jahreszahl_Statistik Dekade Gattung Aachen 2017/18 FU Berlin o.J. Stuttgart o.J. AnzahlZuLesen AnzahlGenannt
2337 Urweider, Raphael Lyrik 2011.0 2010.0 Lyrik 0.0 0.0 0.0 1.103448 2.0
647 Fleißer, Marieluise Ein Pfund Orangen 1926.0 1920.0 Prosa 0.0 0.0 0.0 1.500000 2.0
619 Enzensberger, Hans Magnus Mausoleum 1975.0 1970.0 Lyrik 0.0 0.0 0.0 0.500000 1.0
2158 Schwitters, Kurt Anna Blume 1919.0 1910.0 Lyrik 0.0 0.0 1.0 4.071013 5.0
715 Frischmuth, Barbara Die Klosterschule 1968.0 1960.0 Prosa 0.0 0.0 0.0 1.161290 2.0
In [32]:
print(f"Vorhandene Leselisten : {len(leselisten)}")
print(f"Vorhandene Einträge   : {data.shape[0]}")
print(f"Fehlende Autornamen   : {data.query('Autor.isna()').shape[0]}")
print(f"Fehlende Titel        : {data.query('Titel.isna()').shape[0]}")
print(f"Fehlende Jahreszahlen : {data.query('Jahreszahl_Statistik.isna()').shape[0]}")
print(f"Fehlende Gattungen    : {data.query('Gattung.isna()').shape[0]}")
Vorhandene Leselisten : 42
Vorhandene Einträge   : 2425
Fehlende Autornamen   : 0
Fehlende Titel        : 0
Fehlende Jahreszahlen : 0
Fehlende Gattungen    : 0

5.1 Datengrundlage¶

In [33]:
data[['AnzahlGenannt', 'AnzahlGenannt_normalisiert', 'AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']].corr(method='pearson')
Out[33]:
AnzahlGenannt AnzahlGenannt_normalisiert AnzahlZuLesen AnzahlZuLesen_normalisiert
AnzahlGenannt 1.000000 0.972785 0.980274 0.959902
AnzahlGenannt_normalisiert 0.972785 1.000000 0.975638 0.989566
AnzahlZuLesen 0.980274 0.975638 1.000000 0.973382
AnzahlZuLesen_normalisiert 0.959902 0.989566 0.973382 1.000000
In [34]:
data[['AnzahlGenannt', 'AnzahlGenannt_normalisiert', 'AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']].corr(method='spearman')
Out[34]:
AnzahlGenannt AnzahlGenannt_normalisiert AnzahlZuLesen AnzahlZuLesen_normalisiert
AnzahlGenannt 1.000000 0.855968 0.856018 0.835899
AnzahlGenannt_normalisiert 0.855968 1.000000 0.841561 0.958477
AnzahlZuLesen 0.856018 0.841561 1.000000 0.866056
AnzahlZuLesen_normalisiert 0.835899 0.958477 0.866056 1.000000

5.2 Länge der Leselisten¶

In [35]:
metriken = ['AnzahlGenannt', 'AnzahlZuLesen']

data_plot = pd.DataFrame()
for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste['ListeAnzahlGenannt'] = 1
    data_leseliste['ListeAnzahlGenannt_normalisiert'] = 1/data_leseliste.shape[0]
    data_leseliste['ListeAnzahlZuLesen'] = data_leseliste[leseliste]
    data_leseliste['ListeAnzahlZuLesen_normalisiert'] = data_leseliste[leseliste]/data_leseliste[leseliste].sum()

    for metrik in metriken:
        summe_alle = data_leseliste['Liste'+metrik].sum()
        data_plot.at[leseliste, metrik] = summe_alle

data_plot.sort_values(by=metriken[0], ascending=False)
Out[35]:
AnzahlGenannt AnzahlZuLesen
Trier o.J. 739.0 47.421737
Lausanne o.J. 668.0 668.000000
Hildesheim o.J. 411.0 53.772152
Aachen 2017/18 347.0 44.880692
Wien o.J. 345.0 39.000000
Saarland 2007 344.0 293.250000
Magdeburg 2020 343.0 68.600000
Salzburg o.J. 332.0 264.000000
Jena 2018 331.0 70.750000
Leipzig o.J. 314.0 296.000000
München o.J. 311.0 73.325758
Frankfurt a.M. o.J. 297.0 14.833333
Wuppertal 2015 262.0 262.000000
Würzburg 2003/04 244.0 57.658333
Zürich 2013 241.0 241.000000
FU Berlin o.J. 239.0 239.000000
Dortmund o.J. 231.0 172.000000
Karlsruhe o.J. 230.0 230.000000
Würzburg 2019 227.0 227.000000
Braunschweig o.J. 221.0 56.828929
Gießen o.J. 208.0 208.000000
Stuttgart 2022 202.0 202.000000
Koblenz o.J. 182.0 179.000000
Innsbruck 2023 166.0 18.333333
LA Aachen 2018 165.0 21.952000
Tübingen o.J. 143.0 143.000000
Heidelberg 2017 135.0 66.200000
Passau o.J. 127.0 127.000000
Augsburg 2020 107.0 107.000000
Mannheim o.J. 106.0 106.000000
Eichstätt-Ingolstadt 2007 100.0 100.000000
Oldenburg 2020 99.0 99.000000
Bochum o.J. 98.0 95.000000
Graz 2021 86.0 86.000000
Lüneburg o.J. 79.0 26.333333
Potsdam 2022 76.0 76.000000
Göttingen o.J. 73.0 64.000000
Osnabrück o.J. 68.0 28.333333
Luxemburg o.J. 61.0 61.000000
Köln o.J. 54.0 54.000000
Stuttgart o.J. 50.0 50.000000
Innsbruck o.J. 37.0 37.000000
In [36]:
data_plot.median()
Out[36]:
AnzahlGenannt    205.0
AnzahlZuLesen     81.0
dtype: float64

5.3 Autor*innen¶

In [37]:
data['Autor'].nunique()
Out[37]:
773
In [38]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

data_plot = data.groupby('Autor')[['Geschlecht']+metriken].sum()
data_plot['AnzahlListen'] = (data.groupby('Autor')[leselisten].sum() > 0).sum(axis=1)
data_plot['Geschlecht'] = [str(x)[0] for x in data_plot['Geschlecht']]
for metrik in metriken:
    data_plot[metrik+'_Rang'] = data_plot[metrik].rank(ascending=False)

print(data_plot.drop([x+'_Rang' for x in metriken], axis=1).sort_values(by=metriken[0], ascending=False).head(20))
data_plot.sort_values(by=metriken[0], ascending=False).to_excel("results/top_autorinnen.xlsx")

fig = px.bar(
    data_plot.sort_values(by=metriken[0], ascending=False).head(20),
    x = metriken[0],
    labels = {'Autor':'', metriken[0]:'Häufigkeit'}
)
fig.update_yaxes(categoryorder='total ascending')
fig.update_layout(
    height=700, width = 700,
    showlegend=False,
    xaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18)),
    yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
)
fig.write_image("plots/haeufigste_autorinnen.pdf")
fig.show()
                          Geschlecht  AnzahlZuLesen  AnzahlZuLesen_normalisiert  AnzahlListen
Autor                                                                                        
Goethe, Johann Wolfgang            m     262.604382                    0.054798            42
Schiller, Friedrich                m     166.424373                    0.033645            42
Kleist, Heinrich von               m     125.857400                    0.026944            42
Brecht, Bertolt                    m     114.518668                    0.024774            42
Lessing, Gotthold Ephraim          m     111.924665                    0.023436            42
Kafka, Franz                       m      95.223132                    0.019652            41
Hofmannsthal, Hugo von             m      89.151108                    0.016722            38
Mann, Thomas                       m      82.897052                    0.016905            42
Büchner, Georg                     m      76.941583                    0.017157            41
Eichendorff, Joseph von            m      73.987421                    0.013876            40
Heine, Heinrich                    m      73.656883                    0.012985            37
Schnitzler, Arthur                 m      71.775309                    0.014486            42
Gryphius, Andreas                  m      68.429551                    0.014813            38
Hoffmann, E.T.A.                   m      62.941029                    0.013530            42
Hauptmann, Gerhart                 m      60.165484                    0.013128            42
Fontane, Theodor                   m      59.044436                    0.012084            42
Tieck, Ludwig                      m      57.832940                    0.010753            34
Bachmann, Ingeborg                 w      56.809962                    0.010606            38
Keller, Gottfried                  m      53.915727                    0.010495            39
Benn, Gottfried                    m      52.801080                    0.008793            31
In [39]:
data_plot.loc['Goethe, Johann Wolfgang'][metriken[0]] / data_plot.loc['Schiller, Friedrich'][metriken[0]]
Out[39]:
1.5779202077110304
In [40]:
metrik = 'AnzahlZuLesen'

data_plot = pd.DataFrame()
for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste['ListeAnzahlGenannt'] = 1
    data_leseliste['ListeAnzahlGenannt_normalisiert'] = 1/data_leseliste.shape[0]
    data_leseliste['ListeAnzahlZuLesen'] = data_leseliste[leseliste]
    data_leseliste['ListeAnzahlZuLesen_normalisiert'] = data_leseliste[leseliste]/data_leseliste[leseliste].sum()
    
    summe_alle = data_leseliste['Liste'+metrik].sum()
    summe_goethe = data_leseliste.query("Autor == 'Goethe, Johann Wolfgang'")['Liste'+metrik].sum()
    data_plot.at[leseliste, 'Anteil_Goethe'] = summe_goethe/summe_alle

data_plot = data_plot.sort_values(by = 'Anteil_Goethe', ascending=False)
px.box(
    data_plot,
    points = 'all',
    hover_name = data_plot.index,
    labels = {'value':'', 'variable':''}
)
In [41]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']
top_authors = 200

data_plot = data.groupby('Autor')[metriken+['Geschlecht']].sum()
data_plot['Geschlecht'] = [str(x)[0] for x in data_plot['Geschlecht']]
data_plot = data_plot.sort_values(by=metriken[0], ascending=False)

for i, author in enumerate(data_plot.index):
    if i == 0:
        continue

    last_author = data_plot.iloc[i-1]
    current_author = data_plot.iloc[i]

    last_author_freq = last_author[metriken[0]]
    current_author_freq = current_author[metriken[0]]
    decline = 1 - (current_author_freq / last_author_freq)

    data_plot.at[author, 'decline'] = decline

fig = px.bar(
    data_plot.head(top_authors),
    y = metriken[0],
    labels = {'Autor':'', metriken[0]:'Häufigkeit'}
)
fig.update_xaxes(categoryorder='total descending')
fig.update_layout(
    height=600, width = 1200,
    showlegend=False,
    xaxis=dict(tickfont=dict(size=4), titlefont=dict(size=18)),
    yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
)
fig.show()
In [42]:
fig = px.bar(
    data_plot.head(200),
    y = 'decline',
    labels = {'Autor':'', 'decline':'Abnahme  Häufigkeit gegenüber<br>nächsthäufiger Autor:in in %'}
)
fig.update_layout(
    height=600, width = 1200,
    showlegend=False,
    xaxis=dict(tickfont=dict(size=4), titlefont=dict(size=18)),
    yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
)
fig.show()
In [43]:
data_plot.query("AnzahlZuLesen <= 2").shape[0]
Out[43]:
455
In [44]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

data_plot = data.groupby('Autor')[metriken + ['Geschlecht']].sum()
data_plot['Geschlecht'] = [str(x)[0] for x in data_plot['Geschlecht']]

for metrik in metriken:
    data_plot[metrik+'_Rang'] = data_plot[metrik].rank(ascending=False)
    
data_plot.query("Geschlecht=='w'").nsmallest(10, metriken[0]+'_Rang')
Out[44]:
AnzahlZuLesen AnzahlZuLesen_normalisiert Geschlecht AnzahlZuLesen_Rang AnzahlZuLesen_normalisiert_Rang
Autor
Bachmann, Ingeborg 56.809962 0.010606 w 18.0 18.0
Droste-Hülshoff, Annette von 42.669676 0.010098 w 28.0 21.0
Wolf, Christa 39.130745 0.008140 w 35.0 30.0
Jelinek, Elfriede 38.071676 0.007845 w 38.0 36.0
Seghers, Anna 29.947617 0.006254 w 48.0 43.0
Lasker-Schüler, Else 28.056634 0.004909 w 53.0 55.0
Fleißer, Marieluise 20.205810 0.003954 w 75.0 71.0
La Roche, Sophie von 18.922045 0.004230 w 80.0 67.0
Aichinger, Ilse 17.007765 0.003633 w 85.0 74.0
Günderrode, Karoline von 16.771027 0.002943 w 86.0 86.0
In [45]:
metrik = 'AnzahlZuLesen'

data_plot = pd.DataFrame()
for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste['ListeAnzahlGenannt'] = 1
    data_leseliste['ListeAnzahlGenannt_normalisiert'] = 1/data_leseliste.shape[0]
    data_leseliste['ListeAnzahlZuLesen'] = data_leseliste[leseliste]
    data_leseliste['ListeAnzahlZuLesen_normalisiert'] = data_leseliste[leseliste]/data_leseliste[leseliste].sum()
    
    summe_alle = data_leseliste['Liste'+metrik].sum()
    summe_frauen = data_leseliste.query("Geschlecht == 'w'")['Liste'+metrik].sum()
    data_plot.at[leseliste, 'Frauenanteil'] = summe_frauen/summe_alle
    data_plot.at[leseliste, 'Datum'] = leselisten_meta.query("Leseliste==@leseliste")['Datum'].tolist()[0]

fig = px.bar(
    data_plot.sort_values(by='Frauenanteil'),
    x = 'Frauenanteil',
    orientation='h',
    labels = {'Autor':'', 'Frauenanteil':'Anteil Autorinnen', 'index':''}
)
fig.update_layout(
    height=1100, width = 700,
    showlegend=False,
    xaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18)),
    yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
)
fig.write_image("plots/frauenanteil.pdf")
fig.show()

print(f"Median Anteil Autorinnen : {round(data_plot['Frauenanteil'].median(), 4)}")
Median Anteil Autorinnen : 0.1035
In [46]:
px.scatter(
    data_plot,
    x = 'Datum',
    y = 'Frauenanteil',
    labels = {'Frauenanteil' : 'Anteil Autorinnen'}
)

5.4 Titel¶

In [47]:
metrik = 'AnzahlGenannt'
print(f"Titel insgesamt                            : {data.shape[0]}")

data_plot = data[metrik].clip(upper=data[metrik].quantile(0.95))

fig = px.histogram(
    data_plot,
    labels = {'value': metrik}
)
fig.update_layout(
    height=500, width = 1000,
    showlegend=False,
    xaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18)),
    yaxis=dict(title = "Anzahl Texte", tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
)
# fig.write_image("plots/texte_pro_AnzahlGenannt.pdf")
fig.show()
Titel insgesamt                            : 2425
In [48]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert', 'AnzahlGenannt']

data_plot = data.copy()
for metrik in metriken:
    data_plot[metrik+'_Rang'] = data_plot[metrik].rank(ascending=False)

result_view = top_titles = (
    data_plot
    .sort_values(by=metriken[0], ascending=False)
)[['Autor', 'Titel', 'Jahreszahl_Statistik'] + metriken + [x+'_Rang' for x in metriken]]
result_view.to_excel("results/top_titel.xlsx")

round(result_view.head(30), 5)
Out[48]:
Autor Titel Jahreszahl_Statistik AnzahlZuLesen AnzahlZuLesen_normalisiert AnzahlGenannt AnzahlZuLesen_Rang AnzahlZuLesen_normalisiert_Rang AnzahlGenannt_Rang
897 Grimmelshausen, Johann Jakob Christoph von Der Abentheuerliche Simplicissimus Teutsch 1668.0 30.23840 0.00878 38.0 1.0 1.0 4.0
794 Goethe, Johann Wolfgang Die Leiden des jungen Werthers 1774.0 29.83381 0.00805 38.0 2.0 2.0 4.0
800 Goethe, Johann Wolfgang Faust. Der Tragödie erster Teil 1808.0 28.15702 0.00714 40.0 3.0 4.0 1.0
532 Droste-Hülshoff, Annette von Die Judenbuche. Sittengemälde aus dem gebirgic... 1842.0 28.00732 0.00703 39.0 4.0 5.0 2.0
426 Büchner, Georg Woyzeck 1836.0 26.63315 0.00731 37.0 5.0 3.0 6.0
664 Fontane, Theodor Effi Briest 1896.0 25.03016 0.00639 38.0 6.0 6.0 4.0
1614 Lessing, Gotthold Ephraim Nathan der Weise 1779.0 24.60517 0.00519 35.0 7.0 11.0 9.0
504 Döblin, Alfred Berlin Alexanderplatz 1929.0 24.48562 0.00559 36.0 8.0 8.0 7.0
2235 Storm, Theodor Der Schimmelreiter 1888.0 24.27533 0.00524 35.0 9.0 10.0 9.0
867 Grass, Günter Die Blechtrommel 1959.0 23.28644 0.00498 32.0 10.0 18.0 16.5
831 Goethe, Johann Wolfgang Wilhelm Meisters Lehrjahre 1795.0 22.99770 0.00503 33.0 11.0 16.0 13.0
1027 Hauptmann, Gerhart Die Weber 1892.0 22.57472 0.00532 35.0 12.0 9.0 9.0
1607 Lessing, Gotthold Ephraim Emilia Galotti 1772.0 22.43850 0.00564 33.0 13.0 7.0 13.0
1452 Kleist, Heinrich von Der zerbrochene Krug 1806.0 22.35604 0.00503 34.0 14.0 15.0 11.0
2072 Schiller, Friedrich Maria Stuart 1800.0 22.32834 0.00474 31.0 15.0 22.0 22.5
1343 Kafka, Franz Die Verwandlung 1912.0 22.30958 0.00502 30.0 16.0 17.0 28.5
1341 Kafka, Franz Der Prozess 1925.0 22.14452 0.00489 33.0 17.0 19.0 13.0
577 Eichendorff, Joseph von Aus dem Leben eines Taugenichts 1826.0 21.85124 0.00449 32.0 18.0 26.0 16.5
1775 Moritz, Karl Philipp Anton Reiser 1785.0 21.83566 0.00457 31.0 19.0 23.0 22.5
1861 Novalis Heinrich von Ofterdingen 1802.0 21.28632 0.00402 31.0 20.0 36.0 22.5
801 Goethe, Johann Wolfgang Faust. Der Tragödie zweiter Teil 1832.0 21.23956 0.00513 29.0 21.0 12.0 33.0
1814 Musil, Robert Die Verwirrungen des Zöglings Törless 1906.0 21.22007 0.00508 32.0 22.0 14.0 16.5
1151 Hoffmann, E.T.A. Der Sandmann 1816.0 21.02046 0.00513 31.0 23.0 13.0 22.5
1612 Lessing, Gotthold Ephraim Minna von Barnhelm 1767.0 20.79683 0.00426 31.0 24.0 31.0 22.5
809 Goethe, Johann Wolfgang Iphigenie auf Tauris 1787.0 20.75837 0.00484 32.0 25.0 20.0 16.5
2131 Schnitzler, Arthur Leutnant Gustl 1901.0 20.67338 0.00453 30.0 26.0 25.0 28.5
424 Büchner, Georg Lenz 1839.0 20.15091 0.00405 31.0 27.0 35.0 22.5
1677 Mann, Thomas Die Buddenbrooks 1901.0 19.74370 0.00434 31.0 28.0 28.0 22.5
1184 Hofmannsthal, Hugo von Ein Brief (Chandosbrief) 1902.0 19.69922 0.00427 27.0 29.0 30.0 42.0
796 Goethe, Johann Wolfgang Die Wahlverwandtschaften 1809.0 19.69175 0.00483 31.0 30.0 21.0 22.5
In [49]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

data_autoren = data.groupby('Autor')[metriken].sum()
for metrik in metriken:
    data_autoren[metrik+'_Rang'] = data_autoren[metrik].rank(ascending=False)
data_autoren_specific= data_autoren.loc[['Grimmelshausen, Johann Jakob Christoph von']]

data_autoren_specific
Out[49]:
AnzahlZuLesen AnzahlZuLesen_normalisiert AnzahlZuLesen_Rang AnzahlZuLesen_normalisiert_Rang
Autor
Grimmelshausen, Johann Jakob Christoph von 32.201219 0.009218 43.0 26.0
In [50]:
metrik = 'AnzahlZuLesen'
sample_count, sample_size = 1000, 5

data_plot = pd.DataFrame()
for dekade in tqdm(sorted(data['Dekade'].unique())):
    data_dekade = data.query("Dekade==@dekade")

    data_plot.at[dekade, 'AnzahlGenannt'] = data_dekade.shape[0]
    data_plot.at[dekade, metrik] = data_dekade[metrik].sum()
    
    data_plot.at[dekade, metrik+'_pro_Titel'] = data_plot.at[dekade, metrik]/data_plot.at[dekade, 'AnzahlGenannt']

    sample_means = []
    for i in range(sample_count):
        data_dekade_sample = data_dekade.sample(n=sample_size, replace=True)
        sample_means.append(data_dekade_sample[metrik].sum()/sample_size)

    data_plot.at[dekade, metrik+'_pro_Titel_samples'] = np.array(sample_means, dtype='object')
    data_plot.at[dekade, metrik+'_pro_Titel_samplemean'] = np.mean(sample_means)
  0%|          | 0/43 [00:00<?, ?it/s]
In [51]:
data_plot.drop(metrik+'_pro_Titel_samples', axis = 'columns').head(5)
Out[51]:
AnzahlGenannt AnzahlZuLesen AnzahlZuLesen_pro_Titel AnzahlZuLesen_pro_Titel_samplemean
1600 3.0 8.567439 2.855813 2.873223
1610 4.0 7.314095 1.828524 1.813597
1620 3.0 14.802995 4.934332 4.995017
1630 14.0 21.953336 1.568095 1.574728
1640 16.0 41.685301 2.605331 2.622228
In [52]:
maxdiff = max(abs(data_plot[metrik+'_pro_Titel']-data_plot[metrik+'_pro_Titel_samplemean']))
print(f"Maxdiff AnzahlZuLesen_pro_Titel <> AnzahlZuLesen_pro_Titel_samplemean: {round(maxdiff, 5)}")
Maxdiff AnzahlZuLesen_pro_Titel <> AnzahlZuLesen_pro_Titel_samplemean: 0.16815
In [53]:
fig = px.line(
    data_plot,
    y = metrik+'_pro_Titel',
    hover_data = ['AnzahlGenannt', metrik],
    labels = {'index':''}
)
fig.show()

corr = data_plot[['AnzahlGenannt', metrik+'_pro_Titel']].corr().iloc[0,1]
print(f"Korrelation AnzahlGenannt <> {metrik}_pro_Titel: {round(corr, 2)}")
Korrelation AnzahlGenannt <> AnzahlZuLesen_pro_Titel: -0.24
In [54]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']
autoren = ['Brecht, Bertolt', 'Schiller, Friedrich', 'Goethe, Johann Wolfgang']

data_autoren = data.query("Autor.isin(@autoren)")

data_autoren_AnzahlGenannt = data_autoren.groupby("Autor").size()
print(data_autoren_AnzahlGenannt.to_frame(name='Anzahl Texte').to_markdown())

for metrik in metriken:
    fig = px.box(
        data_autoren,
        x = 'Autor',
        y = metrik,
        points = 'all',
        hover_name = 'Titel',
        hover_data = [metrik+'_Rang']
    )
    fig.show()
| Autor                   |   Anzahl Texte |
|:------------------------|---------------:|
| Brecht, Bertolt         |             44 |
| Goethe, Johann Wolfgang |             55 |
| Schiller, Friedrich     |             39 |
In [55]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

for metrik in metriken:
    data_plot = data.groupby('Dekade')[metrik].sum()
    
    fig = px.bar(
        data_plot,
        labels = {'value':'Häufigkeit', 'Dekade':''}
    )
    fig.update_layout(
        height=400, width = 900,
        showlegend=False,
        xaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "er"),
        yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
    )
    if metrik == metriken[0]:
        fig.write_image("plots/dekaden.pdf")
    print(metrik)
    fig.show()
AnzahlZuLesen
AnzahlZuLesen_normalisiert
In [56]:
author_titles = [
    ['Goethe, Johann Wolfgang', 'Wilhelm Meisters Lehrjahre'],
    ['Keller, Gottfried', 'Die Leute von Seldwyla'],
    ['Heine, Heinrich', 'Deutschland. Ein Wintermärchen*'],
    ['Brecht, Bertolt', 'Die Dreigroschenoper'],
]

data_plot = pd.DataFrame()

for author_title in author_titles:
    author = author_title[0]
    title = author_title[1]

    data_plot = pd.concat([
        data_plot,
        data.query("Autor == @author and Titel == @title")
    ])

data_plot['AnzahlGenannt_rel'] = data_plot['AnzahlGenannt']/len(leselisten)

data_plot[['Autor', 'Titel', 'AnzahlGenannt', 'AnzahlGenannt_rel']]
Out[56]:
Autor Titel AnzahlGenannt AnzahlGenannt_rel
831 Goethe, Johann Wolfgang Wilhelm Meisters Lehrjahre 33.0 0.785714
1407 Keller, Gottfried Die Leute von Seldwyla 20.0 0.476190
1058 Heine, Heinrich Deutschland. Ein Wintermärchen* 18.0 0.428571
356 Brecht, Bertolt Die Dreigroschenoper 23.0 0.547619

5.5 Gattungen¶

In [57]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

for metrik in metriken:
    top_gattungen = pd.DataFrame()
    for gattung in data['Gattung'].unique():
        data_gattung = data.query("Gattung==@gattung")
    
        top_gattungen.at[gattung, 'Anzahl unterschiedliche Titel'] = data_gattung.shape[0]
        top_gattungen.at[gattung, 'Summe Häufigkeit'] = data_gattung[metrik].sum()
        top_gattungen.at[gattung, 'Mittelwert Häufigkeit'] = data_gattung[metrik].mean()
        top_gattungen.at[gattung, 'Median Häufigkeit'] = data_gattung[metrik].median()
    
    top_gattungen = top_gattungen.sort_values(by='Summe Häufigkeit', ascending=False)
    
    print(metrik)
    print(top_gattungen.to_markdown())
    print("\n")
AnzahlZuLesen
|                     |   Anzahl unterschiedliche Titel |   Summe Häufigkeit |   Mittelwert Häufigkeit |   Median Häufigkeit |
|:--------------------|--------------------------------:|-------------------:|------------------------:|--------------------:|
| Prosa               |                            1138 |          2634.38   |                 2.31492 |             1       |
| Drama               |                             344 |          1183.5    |                 3.4404  |             1.09949 |
| Lyrik               |                             647 |          1113.28   |                 1.72068 |             1.02273 |
| Poetik / Essayistik |                             289 |           432.557  |                 1.49674 |             1       |
| Sonstiges           |                               7 |            10.7655 |                 1.53792 |             1       |


AnzahlZuLesen_normalisiert
|                     |   Anzahl unterschiedliche Titel |   Summe Häufigkeit |   Mittelwert Häufigkeit |   Median Häufigkeit |
|:--------------------|--------------------------------:|-------------------:|------------------------:|--------------------:|
| Prosa               |                            1138 |         0.496494   |             0.000436287 |         0.000104204 |
| Drama               |                             344 |         0.240924   |             0.000700361 |         0.000222519 |
| Lyrik               |                             647 |         0.197827   |             0.00030576  |         0.00016457  |
| Poetik / Essayistik |                             289 |         0.0630938  |             0.000218318 |         8.11919e-05 |
| Sonstiges           |                               7 |         0.00166095 |             0.000237278 |         0.000304394 |


In [58]:
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

for metrik in metriken:
    data_plot = data.groupby(['Dekade', 'Gattung'])[metrik].sum().unstack(fill_value=0)
    data_plot = data_plot.div(data_plot.sum(axis=1), axis=0)
    data_plot = data_plot[top_gattungen.index]
    
    fig = px.bar(
        data_plot.loc[1750:2010],
         labels = {'value':'Anteil', 'Dekade':''}   
    )
    fig.update_layout(
        height=400, width = 900,
        legend=dict(font=dict(size=16)),
        xaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "er"),
        yaxis=dict(tickfont=dict(size=16), titlefont=dict(size=18), ticksuffix = "  "),
    )
    if metrik == metriken[0]:
        fig.write_image("plots/gattungen_dekaden.pdf")
        
    print(metrik)
    fig.show()
AnzahlZuLesen
AnzahlZuLesen_normalisiert
In [59]:
# 1860er
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

texte1860 = data.query("Dekade == 1860")
texte1860 = texte1860.sort_values(by=metrik, ascending=False)

print(f"Anzahl Titel : {texte1860.shape[0]}")
print(f"{texte1860[['Autor', 'Titel', 'Gattung']+metriken].head(5)}")
Anzahl Titel : 19
                        Autor                 Titel Gattung  AnzahlZuLesen  AnzahlZuLesen_normalisiert
1739  Meyer, Conrad Ferdinand              Gedichte   Lyrik       8.523011                    0.001446
438            Busch, Wilhelm        Max und Moritz   Prosa       3.435474                    0.001418
1689         Marlitt, Eugenie              Goldelse   Prosa       2.000000                    0.000258
1738  Meyer, Conrad Ferdinand  Erzählungen/Novellen   Prosa       1.238095                    0.000199
1071          Heine, Heinrich              Morphine   Lyrik       1.250000                    0.000165
In [60]:
# Prosa 1880er
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

prosa1880 = data.query("Dekade == 1880 and Gattung == 'Prosa'")
prosa1880 = prosa1880.sort_values(by=metrik, ascending=False)

print(f"Anzahl Titel : {prosa1880.shape[0]} (-1 Papa Hamlet)")
print(f"{prosa1880[['Autor', 'Titel']+metriken].head(5)}")
Anzahl Titel : 30 (-1 Papa Hamlet)
                   Autor                Titel  AnzahlZuLesen  AnzahlZuLesen_normalisiert
2235      Storm, Theodor   Der Schimmelreiter      24.275325                    0.005235
1023  Hauptmann, Gerhart     Bahnwärter Thiel      14.586859                    0.003118
1227          Holz, Arno          Papa Hamlet      10.651313                    0.001866
669     Fontane, Theodor  Irrungen, Wirrungen       6.302230                    0.001019
2089    Schlaf, Johannes          Papa Hamlet       4.353845                    0.000980
In [61]:
# Prosa 1990er
metriken = ['AnzahlZuLesen', 'AnzahlZuLesen_normalisiert']

prosa1990 = data.query("Dekade == 1990 and Gattung == 'Prosa'")
prosa1990 = prosa1990.sort_values(by=metrik, ascending=False)

print(f"Anzahl Titel : {prosa1990.shape[0]}")
print(f"{prosa1990[['Autor', 'Titel']+metriken].head(5)}")
Anzahl Titel : 115
                  Autor                          Titel  AnzahlZuLesen  AnzahlZuLesen_normalisiert
1516  Kracht, Christian                      Faserland      14.268583                    0.002736
1491       Klüger, Ruth                   weiter leben       8.296320                    0.001423
2300          Timm, Uwe  Die Entdeckung der Currywurst       5.338052                    0.001139
273       Beyer, Marcel                      Flughunde       5.652805                    0.001074
2146      Schulze, Ingo                 Simple Stories       5.764039                    0.000923

6. Diskussion der Befunde: Leselisten und Kanon¶

In [62]:
results = pd.DataFrame()

for leseliste in leselisten:
    data_leseliste = data[data[leseliste] > 0].copy()
    data_leseliste['ListeAnzahlGenannt'] = 1
    data_leseliste['ListeAnzahlZuLesen'] = data_leseliste[leseliste]
    data_leseliste['ListeAnzahlZuLesen_extern'] = data_leseliste[[x for x in leselisten if x != leseliste]].sum(axis=1)

    results.at[leseliste, 'AnzahlGenannt'] = data_leseliste['ListeAnzahlGenannt'].sum()
    results.at[leseliste, 'AnzahlZuLesen'] = data_leseliste['ListeAnzahlZuLesen'].sum()
    results.at[leseliste, 'AnzahlZuLesen_extern'] = data_leseliste['ListeAnzahlZuLesen_extern'].sum()

results['AnzahlZuLesen_extern_per_title_mean'] = results['AnzahlZuLesen_extern'] / results['AnzahlGenannt']
In [63]:
px.scatter(
    results,
    x = 'AnzahlGenannt',
    y = 'AnzahlZuLesen_extern_per_title_mean'
)